package cn.itcast.bos.service.take_delivery.impl;

import java.util.Date;
import java.util.UUID;

import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.Session;
import javax.ws.rs.core.MediaType;

import org.apache.commons.lang.RandomStringUtils;
import org.apache.cxf.jaxrs.client.WebClient;
import org.bouncycastle.mail.smime.examples.CreateCompressedMail;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.itcast.bos.dao.base.AreaDao;
import cn.itcast.bos.dao.base.FixedAreaDao;
import cn.itcast.bos.dao.take_delivery.OrderDao;
import cn.itcast.bos.dao.take_delivery.WorkBillDao;
import cn.itcast.bos.domain.base.Area;
import cn.itcast.bos.domain.base.Courier;
import cn.itcast.bos.domain.base.FixedArea;
import cn.itcast.bos.domain.base.SubArea;
import cn.itcast.bos.domain.take_delivery.Order;
import cn.itcast.bos.domain.take_delivery.WorkBill;
import cn.itcast.bos.service.take_delivery.OrderService;

@Service
@Transactional
public class OrderServiceImpl implements OrderService {

	@Autowired
	private OrderDao orderDao;
	@Autowired
	private FixedAreaDao fixedAreaDao;

	@Autowired
	private AreaDao areaDao;

	@Autowired
	private WorkBillDao workBillDao;
	
	@Autowired
	
	private JmsTemplate jmsTemplate;
	
	/**
	 * 在保存订单之前要先进行分单操作，订单要通过工单绑定对应的快递员,发送短信运用消息队列
	 */
	@Override
	public void saveOrder(Order order) {
	//因为保存的时候会保存寄件人的市区信息和收件人的市区信息，但是此时order里面的信息是瞬时态的，持久态的无法关联保存瞬时态的
	//应该重新从数据库查询内容，添加到order里面
	Area sendArea = order.getSendArea();
	// 根据省市区查询已经存在的地区
	
	Area area1 = areaDao.findAreaByProvinceAndCityAndDistrict(sendArea.getProvince(), sendArea.getCity(),
			sendArea.getDistrict());
	order.setSendArea(area1);
    
	
	 // 重新保存收获地址 
	 Area recArea = order.getRecArea();
	 Area area2 = areaDao.findAreaByProvinceAndCityAndDistrict(recArea.getProvince(), recArea.getCity(), recArea.getDistrict());
	 order.setRecArea(area2);	
		
		
		// 首先看地址是否与数据库完全一致，一致的就直接分单给对应的快递员

		String fixedAreaId = WebClient
				.create("http://localhost:8081/crm_management/service/customerService/customer/fixedAreaId?address="
						+ order.getSendAddress())
				.accept(MediaType.APPLICATION_JSON).get(String.class);

		
		// 判断id是否存在
		if (fixedAreaId != null) {
			// 根据定区id找到对应的定区，然后找到对用的快递员
			FixedArea fixedArea = fixedAreaDao.findOne(fixedAreaId);
			// 根据查询的定区找到对应的快递员，这里为了简便，直接将订单分配给了快递员集合的第一个人
			Courier courier = fixedArea.getCouriers().iterator().next();

			if (courier != null) {

				// 将快递员关联到订单上
				order.setCourier(courier);
				// 保存订单之前生成订单编号,订单编号是字符串类型
				order.setOrderNum(UUID.randomUUID().toString());
				
				
				
				
				orderDao.save(order);

				// 生成工单，给快递员发送短信
				createWorkBill(order);
				return;
			}
		}

		// 其次,根据寄件地址，查询分区关键字，匹配地址
		// 获取对应的分区，遍历
		for (SubArea subArea : area1.getSubareas()) {
			// 根据用户下单的地址去匹配对应的分区关键字，有的换就找到对应的定区
			if (order.getSendAddress().contains(subArea.getKeyWords())) {

				Courier courier = subArea.getFixedArea().getCouriers().iterator().next();

				if (courier != null) {

					order.setCourier(courier);

					order.setOrderNum(UUID.randomUUID().toString());

					orderDao.save(order);

					// 生成工单，发送短信
					createWorkBill(order);
					return;
				}

			}

		}

		// 看订单地址中是否存在辅助关键字
		for (SubArea subArea : area1.getSubareas()) {

			if (order.getSendAddress().contains(subArea.getAssistKeyWords())) {
				Courier courier = subArea.getFixedArea().getCouriers().iterator().next();

				if (courier != null) {

					order.setCourier(courier);

					order.setOrderNum(UUID.randomUUID().toString());

					orderDao.save(order);


					// 生成工单，发送短信
					createWorkBill(order);
					return;

				}
			}

		}
		
		
		//如果以上条件均不匹配，就进行人工分单,数据库中规定了订单类型1是自动分单，2是人工分单
		order.setOrderType("2");
		orderDao.save(order);
		
	}

	//定义生成工单和发送信息的方法
	private void createWorkBill( final Order order){
		
	//生成工单
	WorkBill workbill=new WorkBill();
	workbill.setType("新");
	workbill.setPickstate("新单");
	workbill.setBuildtime(new Date());
	workbill.setRemark(order.getRemark());//订单备注
	
	//产生一个4位随机数，作为短信序号
     final String smsNumber = RandomStringUtils.randomNumeric(4);
     workbill.setSmsNumber(smsNumber); 
     workbill.setOrder(order);
     workbill.setCourier(order.getCourier());
     //保存工单
     workBillDao.save(workbill);
     
     //调用消息队列，发送消息，通知消费者发送短信
     jmsTemplate.send("workbillNotice",new MessageCreator() {
		
		@Override
		public Message createMessage(Session session) throws JMSException {
			MapMessage mapMessage = session.createMapMessage();
			mapMessage.setString("telephone", order.getTelephone());
			mapMessage.setString(
					"msg",
					"短信序号：" + smsNumber + ",取件地址：" + order.getSendAddress()
							+ ",联系人:" + order.getSendName() + ",手机:"
							+ order.getSendMobile() + "，快递员捎话："
							+ order.getSendMobileMsg());
			
			
			return mapMessage;
			
			
		}
	});
     //修改工单状态
     workbill.setPickstate("已通知");
     
	}

	@Override
	public Order findByOrderNum(String orderNum) {
	
		return orderDao.findByOrderNum(orderNum);
	}
	
	

		
}
